package com.wurd.youdao;

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

public class YoudaoSingleSocket extends WebSocketServer {

    private WebSocket socket;

    private String result;

    private int capacity;

    private AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    private ArrayBlockingQueue queue;

    private Translator translator;

    private boolean auto = false;


    public YoudaoSingleSocket(int port) {
        this(new InetSocketAddress(port), 100);
    }

    public YoudaoSingleSocket(int port, int capacity) {
        this(new InetSocketAddress(port), capacity);
    }

    public YoudaoSingleSocket(InetSocketAddress address, int capacity) {
        super(address);
        this.capacity = capacity;
        this.queue = new ArrayBlockingQueue(this.capacity);
    }

    @Deprecated
    public synchronized String get(String str) throws Exception {
        if(auto){
            throw new Exception("auto: " + auto);
        }
        if (socket == null || socket.isClosed()) {
            throw new Exception("socket is null");
        }
        atomicBoolean.set(false);
        socket.send(str);
        while (!atomicBoolean.get()) {
        }
        String r = result;
        atomicBoolean.set(false);
        return r;
    }

    public void putTranslator(String str, Consumer<String> consumer) throws Exception {
        if(!auto){
            throw new Exception("auto: " + auto);
        }
        queue.put(new Translator(str, consumer));
    }

    private static class Translator {
        private String str;
        private Consumer<String> consumer;

        Translator(String str, Consumer<String> consumer) {
            this.str = str;
            this.consumer = consumer;
        }
    }

    @Override
    public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
        System.out.println("open");
        socket = webSocket;
    }

    @Override
    public void onClose(WebSocket webSocket, int i, String s, boolean b) {
        System.out.println("close");
    }

    @Override
    public void onMessage(WebSocket webSocket, String s) {
        System.out.println("message");
        if (translator != null) {
            translator.consumer.accept(s);
            atomicBoolean.compareAndSet(false, true);
        } else {
            result = s;
            atomicBoolean.compareAndSet(false, true);
        }
    }

    @Override
    public void onError(WebSocket webSocket, Exception e) {
        System.out.println("error: " + e.getMessage());
    }

    @Override
    public void onStart() {
        System.out.println("start");
        if(auto){
            genWorker();
        }
    }

    private void genWorker() {
        new Thread(() -> {
            while (true) {
                try {
                    if (socket == null || socket.isClosed()) {
                        Thread.sleep(1000);
                        throw new Exception("socket is null");
                    }
                    translator = (Translator) queue.take();
                    atomicBoolean.set(false);
                    socket.send(translator.str);
                    while (!atomicBoolean.get()) {
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
